
/**
 * 简单实现一个发布订阅模式
 * on emit off once
 * 两个实例 - 发布(告诉所有的任务重新执行) 订阅(收集所有的任务)
 */
 class EventEmitter {
  constructor () {
    this.cache = {}
  }

  // 订阅
  on (name, fn) {
    const tasks = this.cache[name]
    if (tasks) {
      tasks.push(fn)
    } else {
      this.cache[name] = [fn]
    }
  }

  // 移除任务
  off (name, fn) {
    let tasks = this.cache[name]
    if (tasks) {
      // 静态拷贝一些 防止有任务正在添加进来 而后移除出错
      const index = tasks.findIndex(item => item === fn)
      if (index > -1) {
        tasks.splice(index, 1)
      }
    }
  }

  // 发布
  emit (name, ...args) {
    // 只针对当前存在的 后来又来的订阅者当前这次不会触发
    const tasks = this.cache[name].slice()
    if (tasks) {
      for (let fn of tasks) {
        fn(args)
      }
    }
  }

  // 一次订阅
  once (name, fn) {
    const _this = this
    function on () {
      fn()
      _this.off(name, on)
    }
    this.on(name, on)
  }
}

const pubSub = new EventEmitter()

pubSub.on('event1', () => {
  console.log(1111, '第一个 event1 的事件触发回调')
})

const cb2 =  () => {
  console.log(2222, '第二个 event1 的事件触发回调')
}

pubSub.on('event1', cb2)

pubSub.on('event2', () => {
  console.log(1111, '第一个 event2 的事件触发回调')
})


pubSub.emit('event1')
pubSub.off('event1', cb2)
pubSub.emit('event1')

pubSub.once('event3', () => {
  console.log(1111, '第一个 event3 的事件触发回调')
})

// pubSub.emit('event3')

// pubSub.emit('event3')
